import styled from 'styled-components';
import React, { CSSProperties, FC, useCallback, useEffect, useState } from 'react';
import { Tree, Card, Button, Collapse } from 'antd';
import type { TreeDataNode, TreeProps } from 'antd';
import { PlusOutlined, InfoCircleOutlined } from '@ant-design/icons';
import { open, save } from '@tauri-apps/plugin-dialog';

import { MarkdownView } from '@/components';

import INSTALL_MD from './g01-server-install.md?raw';
import { builderServerConfigExport, ClassRelationCondition, dsFind, ComparsionOperator, ProjectApplication } from '@/services/local';
import { CLASS_CLASS_IDENTIFIER, DATASOURCE_CLASS_IDENTIFIER, DOMAIN_CLASS_IDENTIFIER, PROJECT_APPLICATION_CLASS_IDENTIFIER, PROJECT_CLASS_IDENTIFIER, SCHEDULER_TASK_CLASS_IDENTIFIER } from '@/services/constants';

export interface ApplicationG01ServerPanelProps {
    style?: CSSProperties;
    application: ProjectApplication;
}

export const ApplicationG01ServerPanel: FC<ApplicationG01ServerPanelProps> = (props) => {

    const [loading, setLoading] = useState<boolean>(false);

    const [isModalOpen, setIsModalOpen] = useState(false);

    const [selected, setSelected] = useState<{ domains: string[], datasources: string[], tasks: string[], features: string[] }>({
        domains: [], datasources: [], tasks: [], features: []
    });

    return (
        <Card style={{ width: '100%', height: '100%' }}
            styles={{
                body: {
                    width: '100%',
                    height: '100%',
                    ...props.style
                },
            }}
            title={'编排'}
            extra={
                <>
                    <Button type={'primary'} icon={<PlusOutlined />} onClick={async () => {
                        console.log(selected);
                        let file = await save({
                            title: '',
                            filters: [{
                                name: 'zip',
                                extensions: ['zip']
                            }],
                            canCreateDirectories: true
                        }) as any;

                        if (!file) {
                            return;
                        }
                        console.log(file);
                        try {
                            let res = await builderServerConfigExport(file, {
                                domain: {
                                    domains: selected.domains
                                },
                                scheduler: {
                                    tasks: selected.tasks
                                },
                                features: selected.features
                            });
                            //提示导出成功
                        } catch (err) {
                            console.error(err);
                        }
                    }}>导出</Button>
                </>
            }>
            <Container>
                <FeatureTree style={{ width: '100%', height: '60%' }} application={props.application} onChange={async (value) => {
                    setSelected(value);
                }}></FeatureTree>
                <MarkdownView style={{ width: '100%', flex: 1 }} script={INSTALL_MD} title={'使用说明'}></MarkdownView>
            </Container>
        </Card>
    );
}

const Container = styled.div`
    height: calc(100% - 40px);
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
`;


export interface FeatureTreeProps {
    style?: CSSProperties;
    application: ProjectApplication;
    onChange: (value: { domains: string[], datasources: string[], tasks: string[], features: string[] }) => Promise<void>
}

const FeatureTree: FC<FeatureTreeProps> = (props) => {

    const [loading, setLoading] = useState<boolean>();

    const [category, setCategory] = useState<string[]>(['domains', 'datasources', 'tasks', 'features']);

    const [domains, setDomains] = useState<string[]>([]);

    const [datasources, setDatasources] = useState<string[]>([]);

    const [tasks, setTasks] = useState<string[]>([]);

    const [features, setFeatures] = useState<string[]>([]);

    const categories: any[] = [
        {
            title: '知识域',
            key: 'domains',
        },
        {
            title: '数据源',
            key: 'datasources',
        },
        {
            title: '数据流',
            key: 'tasks',
        },
        {
            title: '功能',
            key: 'features',
        },
    ];

    useEffect(() => {
        props.onChange && props.onChange({ domains, datasources, tasks, features })
    }, [domains, datasources, tasks, features]);

    return (
        <FeatureTreeContainer style={props.style}>
            <Collapse
                style={{ width: '50%' }}
                accordion={false}
                bordered={false}
                activeKey={category}
                onChange={async (keys) => {
                    console.log(keys);
                    setCategory(keys);
                }}
                expandIconPosition={"start"}
                destroyInactivePanel={false}
                items={categories.map((category, index) => {
                    return {
                        key: category.key,
                        label: category.title,
                        children: <FeatureList application={props.application} category={category.key} onSelect={async (category, keys) => {
                            if (category === 'domains') {
                                setDomains(keys);
                            } else if (category === 'datasources') {
                                setDatasources(keys);
                            } else if (category === 'tasks') {
                                setTasks(keys);
                            } else if (category === 'features') {
                                setFeatures(keys);
                            }
                        }} onCheck={async (category, keys) => {
                            if (category === 'domains') {
                                setDomains(keys);
                            } else if (category === 'datasources') {
                                setDatasources(keys);
                            } else if (category === 'tasks') {
                                setTasks(keys);
                            } else if (category === 'features') {
                                setFeatures(keys);
                            }
                        }}></FeatureList>,
                        styles: {
                            body: {
                                padding: '0'
                            }
                        },
                        extra: <InfoCircleOutlined
                            onClick={async (event) => {
                                event.stopPropagation();
                            }}
                        />
                    }
                })}
            />
            <FeatureReadme>

            </FeatureReadme>
        </FeatureTreeContainer>
    );
}


const FeatureTreeContainer = styled.div`
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    justify-content: flex-start;
`;

const FeatureReadme = styled.div`
    flex:1;
`;



export interface FeatureListProps {
    style?: CSSProperties;
    category: string;
    application: ProjectApplication;
    onSelect: (category: string, selected: string[]) => Promise<void>;
    onCheck: (category: string, selected: string[]) => Promise<void>;
}

interface CategoryTreeNode {
    title: string;
    key: string;
    icon?: any;
    isLeaf?: boolean;
    children: CategoryTreeNode[];
}


const FeatureList: FC<FeatureListProps> = (props) => {

    const [loading, setLoading] = useState<boolean>();

    const [treeData, setTreeData] = useState<Array<CategoryTreeNode>>([]);

    const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);

    const request = async (category: string, application: ProjectApplication) => {
        if (!category) return;
        let class_identifier = '';
        if (props.category === 'domains') {
            class_identifier = DOMAIN_CLASS_IDENTIFIER;
        } else if (props.category === 'datasources') {
            class_identifier = DATASOURCE_CLASS_IDENTIFIER;
        } else if (props.category === 'tasks') {
            class_identifier = SCHEDULER_TASK_CLASS_IDENTIFIER;
        } else if (props.category === 'features') {
            class_identifier = DATASOURCE_CLASS_IDENTIFIER;
        } else {
            return;
        }
        let relations: ClassRelationCondition[] = [
            {
                conditions: {
                    class_identifier: PROJECT_CLASS_IDENTIFIER,
                    direction: 'obverse',
                },
                class_conditions: {
                    attributes: [{
                        name: 'project_identifier',
                        operator: ComparsionOperator.Equal,
                        value: props.application.project_identifier,
                    }]
                }
            }
        ];
        let checkRelations: ClassRelationCondition[] = [
            {
                conditions: {
                    class_identifier: PROJECT_APPLICATION_CLASS_IDENTIFIER,
                    direction: 'obverse',
                },
                class_conditions: {
                    attributes: [{
                        name: 'application_identifier',
                        operator: ComparsionOperator.Equal,
                        value: props.application.identifier,
                    }]
                }
            }
        ];
        let all = await dsFind(0, class_identifier, {
            attributes: [],
            relations: relations
        });
        let checks = await dsFind(0, class_identifier, {
            attributes: [],
            relations: checkRelations
        });

        setTreeData(all.data.map((objItem, index) => {
            return {
                title: objItem.title,
                key: objItem.identifier,
                isLeaf: true,
                children: []
            };
        }));
        setCheckedKeys(checks.data.map(item => item.identifier));

    };

    useEffect(() => {
        request(props.category, props.application);
    }, [props.application, props.category]);

    return (
        <TreeContainer style={props.style}>
            <Tree
                checkable
                showIcon={true}
                showLine={true}
                treeData={treeData}
                defaultExpandAll={true}
                checkedKeys={checkedKeys}
                onCheck={async (checkedKeysValue) => {
                    console.log('onCheck', checkedKeysValue);
                    setCheckedKeys(checkedKeysValue);
                    if (checkedKeysValue && checkedKeysValue.length > 0) {
                        props.onCheck(props.category, checkedKeysValue);
                    } else {
                        props.onCheck(props.category, []);
                    }
                }}
                onSelect={async (selectedKeys, e: { selected: boolean, selectedNodes, node, event }) => {
                    console.log(selectedKeys, e);
                    if (selectedKeys && selectedKeys.length > 0) {
                        props.onSelect(props.category, selectedKeys);
                    } else {
                        props.onSelect(props.category, []);
                    }
                }}
            />
        </TreeContainer>
    );
}


const TreeContainer = styled.div`
    flex: 1;
    width: 100%;
`;